home *** CD-ROM | disk | FTP | other *** search
/ Apple Developer Connection Student Program / ADC Tools Sampler CD Disk 3 1999.iso / Metrowerks CodeWarrior / Java Support / Java_Source / Java2 / src / java / awt / MenuBar.java < prev    next >
Encoding:
Java Source  |  1999-05-28  |  11.4 KB  |  421 lines  |  [TEXT/CWIE]

  1. /*
  2.  * @(#)MenuBar.java    1.46 98/09/04
  3.  *
  4.  * Copyright 1995-1998 by Sun Microsystems, Inc.,
  5.  * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
  6.  * All rights reserved.
  7.  *
  8.  * This software is the confidential and proprietary information
  9.  * of Sun Microsystems, Inc. ("Confidential Information").  You
  10.  * shall not disclose such Confidential Information and shall use
  11.  * it only in accordance with the terms of the license agreement
  12.  * you entered into with Sun.
  13.  */
  14. package java.awt;
  15.  
  16. import java.util.Vector;
  17. import java.util.Enumeration;
  18. import java.awt.peer.MenuBarPeer;
  19. import java.awt.event.KeyEvent;
  20.  
  21. /**
  22.  * The <code>MenuBar</code> class encapsulates the platform's
  23.  * concept of a menu bar bound to a frame. In order to associate
  24.  * the menu bar with a <code>Frame</code> object, call the
  25.  * frame's <code>setMenuBar</code> method.
  26.  * <p>
  27.  * <A NAME="mbexample"></A><!-- target for cross references -->
  28.  * This is what a menu bar might look like:
  29.  * <p>
  30.  * <img src="doc-files/MenuBar-1.gif"
  31.  * ALIGN=center HSPACE=10 VSPACE=7>
  32.  * <p>
  33.  * A menu bar handles keyboard shortcuts for menu items, passing them
  34.  * along to its child menus.
  35.  * (Keyboard shortcuts, which are optional, provide the user with
  36.  * an alternative to the mouse for invoking a menu item and the
  37.  * action that is associated with it.)
  38.  * Each menu item can maintain an instance of <code>MenuShortcut</code>.
  39.  * The <code>MenuBar</code> class defines several methods,
  40.  * {@link MenuBar#shortcuts} and
  41.  * {@link MenuBar#getShortcutMenuItem}
  42.  * that retrieve information about the shortcuts a given
  43.  * menu bar is managing.
  44.  *
  45.  * @version 1.46, 09/04/98
  46.  * @author Sami Shaio
  47.  * @see        java.awt.Frame
  48.  * @see        java.awt.Frame#setMenuBar(java.awt.MenuBar)
  49.  * @see        java.awt.Menu
  50.  * @see        java.awt.MenuItem
  51.  * @see        java.awt.MenuShortcut
  52.  * @since      JDK1.0
  53.  */
  54. public class MenuBar extends MenuComponent implements MenuContainer {
  55.  
  56.     static {
  57.         /* ensure that the necessary native libraries are loaded */
  58.     Toolkit.loadLibraries();
  59.         initIDs();
  60.     }
  61.  
  62.     /**
  63.      * This field represents a vector of the
  64.      * actual menus that will be part of the MenuBar.
  65.      *
  66.      * @serial
  67.      * @see countMenus()
  68.      */
  69.     Vector menus = new Vector();
  70.  
  71.     /**
  72.      * This menu is a special menu dedicated to
  73.      * help.  The one thing to note about this menu
  74.      * is that on some platforms it appears at the
  75.      * right edge of the menubar.
  76.      *
  77.      * @serial
  78.      * @see getHelpMenu()
  79.      * @see setHelpMenu()
  80.      */
  81.     Menu helpMenu;
  82.  
  83.     private static final String base = "menubar";
  84.     private static int nameCounter = 0;
  85.  
  86.     /*
  87.      * JDK 1.1 serialVersionUID
  88.      */
  89.      private static final long serialVersionUID = -4930327919388951260L;
  90.  
  91.     /**
  92.      * Creates a new menu bar.
  93.      */
  94.     public MenuBar() {
  95.     }
  96.  
  97.     /**
  98.      * Construct a name for this MenuComponent.  Called by getName() when
  99.      * the name is null.
  100.      */
  101.     String constructComponentName() {
  102.         synchronized (getClass()) {
  103.         return base + nameCounter++;
  104.     }
  105.     }
  106.  
  107.     /**
  108.      * Creates the menu bar's peer.  The peer allows us to change the
  109.      * appearance of the menu bar without changing any of the menu bar's
  110.      * functionality.
  111.      */
  112.     public void addNotify() {
  113.         synchronized (getTreeLock()) {
  114.         if (peer == null)
  115.             peer = Toolkit.getDefaultToolkit().createMenuBar(this);
  116.  
  117.         int nmenus = getMenuCount();
  118.         for (int i = 0 ; i < nmenus ; i++) {
  119.             getMenu(i).addNotify();
  120.         }
  121.     }
  122.     }
  123.  
  124.     /**
  125.      * Removes the menu bar's peer.  The peer allows us to change the
  126.      * appearance of the menu bar without changing any of the menu bar's
  127.      * functionality.
  128.      */
  129.     public void removeNotify() {
  130.         synchronized (getTreeLock()) {
  131.         int nmenus = getMenuCount();
  132.         for (int i = 0 ; i < nmenus ; i++) {
  133.             getMenu(i).removeNotify();
  134.         }
  135.         super.removeNotify();
  136.     }
  137.     }
  138.  
  139.     /**
  140.      * Gets the help menu on the menu bar.
  141.      * @return    the help menu on this menu bar.
  142.      */
  143.     public Menu getHelpMenu() {
  144.     return helpMenu;
  145.     }
  146.  
  147.     /**
  148.      * Sets the help menu on this menu bar to be the specified menu.
  149.      * @param     m    the menu to be set as the help menu.
  150.      */
  151.     public void setHelpMenu(Menu m) {
  152.         synchronized (getTreeLock()) {
  153.         if (helpMenu == m) {
  154.             return;
  155.         }
  156.         if (helpMenu != null) {
  157.             helpMenu.removeNotify();
  158.         helpMenu.parent = null;
  159.         }
  160.         if (m.parent != this) {
  161.             add(m);
  162.         }
  163.         helpMenu = m;
  164.         if (m != null) {
  165.             m.isHelpMenu = true;
  166.         m.parent = this;
  167.         MenuBarPeer peer = (MenuBarPeer)this.peer;
  168.         if (peer != null) {
  169.             if (m.peer == null) {
  170.                 m.addNotify();
  171.             }
  172.             peer.addHelpMenu(m);
  173.         }
  174.         }
  175.     }
  176.     }
  177.  
  178.     /**
  179.      * Adds the specified menu to the menu bar.
  180.      * @param        m   the menu to be added.
  181.      * @return       the menu added.
  182.      * @see          java.awt.MenuBar#remove(int)
  183.      * @see          java.awt.MenuBar#remove(java.awt.MenuComponent)
  184.      */
  185.     public Menu add(Menu m) {
  186.         synchronized (getTreeLock()) {
  187.         if (m.parent != null) {
  188.             m.parent.remove(m);
  189.         }
  190.         menus.addElement(m);
  191.         m.parent = this;
  192.  
  193.         MenuBarPeer peer = (MenuBarPeer)this.peer;
  194.         if (peer != null) {
  195.             if (m.peer == null) {
  196.             m.addNotify();
  197.         }
  198.         peer.addMenu(m);
  199.         }
  200.         return m;
  201.     }
  202.     }
  203.  
  204.     /**
  205.      * Removes the menu located at the specified
  206.      * index from this menu bar.
  207.      * @param        index   the position of the menu to be removed.
  208.      * @see          java.awt.MenuBar#add(java.awt.Menu)
  209.      */
  210.     public void remove(int index) {
  211.         synchronized (getTreeLock()) {
  212.         MenuBarPeer peer = (MenuBarPeer)this.peer;
  213.         if (peer != null) {
  214.             Menu m = getMenu(index);
  215.         m.removeNotify();
  216.         m.parent = null;
  217.         peer.delMenu(index);
  218.         }
  219.         menus.removeElementAt(index);
  220.     }
  221.     }
  222.  
  223.     /**
  224.      * Removes the specified menu component from this menu bar.
  225.      * @param        m the menu component to be removed.
  226.      * @see          java.awt.MenuBar#add(java.awt.Menu)
  227.      */
  228.     public void remove(MenuComponent m) {
  229.         synchronized (getTreeLock()) {
  230.         int index = menus.indexOf(m);
  231.         if (index >= 0) {
  232.             remove(index);
  233.         }
  234.     }
  235.     }
  236.  
  237.     /**
  238.      * Gets the number of menus on the menu bar.
  239.      * @return     the number of menus on the menu bar.
  240.      * @since      JDK1.1
  241.      */
  242.     public int getMenuCount() {
  243.     return countMenus();
  244.     }
  245.  
  246.     /**
  247.      * @deprecated As of JDK version 1.1,
  248.      * replaced by <code>getMenuCount()</code>.
  249.      */
  250.     public int countMenus() {
  251.     return getMenuCountImpl();
  252.     }
  253.  
  254.     /*
  255.      * This is called by the native code, so client code can't
  256.      * be called on the toolkit thread.
  257.      */
  258.     final int getMenuCountImpl() {
  259.     return menus.size();
  260.     }
  261.  
  262.     /**
  263.      * Gets the specified menu.
  264.      * @param      i the index position of the menu to be returned.
  265.      * @return     the menu at the specified index of this menu bar.
  266.      */
  267.     public Menu getMenu(int i) {
  268.     return getMenuImpl(i);
  269.     }
  270.  
  271.     /*
  272.      * This is called by the native code, so client code can't
  273.      * be called on the toolkit thread.
  274.      */
  275.     final Menu getMenuImpl(int i) {
  276.     return (Menu)menus.elementAt(i);
  277.     }
  278.  
  279.     /**
  280.      * Gets an enumeration of all menu shortcuts this menu bar
  281.      * is managing.
  282.      * @return      an enumeration of menu shortcuts that this
  283.      *                      menu bar is managing.
  284.      * @see         java.awt.MenuShortcut
  285.      * @since       JDK1.1
  286.      */
  287.     public synchronized Enumeration shortcuts() {
  288.         Vector shortcuts = new Vector();
  289.     int nmenus = getMenuCount();
  290.     for (int i = 0 ; i < nmenus ; i++) {
  291.             Enumeration e = getMenu(i).shortcuts();
  292.             while (e.hasMoreElements()) {
  293.                 shortcuts.addElement(e.nextElement());
  294.             }
  295.     }
  296.         return shortcuts.elements();
  297.     }
  298.  
  299.     /**
  300.      * Gets the instance of <code>MenuItem</code> associated
  301.      * with the specified <code>MenuShortcut</code> object,
  302.      * or <code>null</code> if none of the menu items being managed
  303.      * by this menu bar is associated with the specified menu
  304.      * shortcut.
  305.      * @param        s the specified menu shortcut.
  306.      * @see          java.awt.MenuItem
  307.      * @see          java.awt.MenuShortcut
  308.      * @since        JDK1.1
  309.      */
  310.      public MenuItem getShortcutMenuItem(MenuShortcut s) {
  311.     int nmenus = getMenuCount();
  312.     for (int i = 0 ; i < nmenus ; i++) {
  313.             MenuItem mi = getMenu(i).getShortcutMenuItem(s);
  314.             if (mi != null) {
  315.                 return mi;
  316.             }
  317.     }
  318.         return null;  // MenuShortcut wasn't found
  319.      }
  320.  
  321.     /*
  322.      * Post an ACTION_EVENT to the target of the MenuPeer
  323.      * associated with the specified keyboard event (on
  324.      * keydown).  Returns true if there is an associated
  325.      * keyboard event.
  326.      */
  327.     boolean handleShortcut(KeyEvent e) {
  328.         // Is it a key event?
  329.         int id = e.getID();
  330.         if (id != KeyEvent.KEY_PRESSED && id != KeyEvent.KEY_RELEASED) {
  331.             return false;
  332.         }
  333.  
  334.         // Is the accelerator modifier key pressed?
  335.         int accelKey = Toolkit.getDefaultToolkit().getMenuShortcutKeyMask();
  336.         if ((e.getModifiers() & accelKey) == 0) {
  337.             return false;
  338.         }
  339.  
  340.         // Pass MenuShortcut on to child menus.
  341.     int nmenus = getMenuCount();
  342.     for (int i = 0 ; i < nmenus ; i++) {
  343.         Menu m = getMenu(i);
  344.             if (m.handleShortcut(e)) {
  345.                 return true;
  346.             }
  347.         }
  348.         return false;
  349.     }
  350.  
  351.     /**
  352.      * Deletes the specified menu shortcut.
  353.      * @param     s the menu shortcut to delete.
  354.      * @since     JDK1.1
  355.      */
  356.     public void deleteShortcut(MenuShortcut s) {
  357.     int nmenus = getMenuCount();
  358.     for (int i = 0 ; i < nmenus ; i++) {
  359.         getMenu(i).deleteShortcut(s);
  360.         }
  361.     }
  362.  
  363.     /* Serialization support.  Restore the (transient) parent
  364.      * fields of Menubar menus here.
  365.      */
  366.  
  367.     /**
  368.      * The MenuBar's serialized data version.
  369.      *
  370.      * @serial
  371.      */
  372.     private int menuBarSerializedDataVersion = 1;
  373.  
  374.     /**
  375.      * Writes default serializable fields to stream.  Writes
  376.      * a list of serializable ItemListener(s) as optional data.
  377.      * The non-serializable ItemListner(s) are detected and
  378.      * no attempt is made to serialize them.
  379.      *
  380.      * @serialData Null terminated sequence of 0 or more pairs.
  381.      *             The pair consists of a String and Object.
  382.      *             The String indicates the type of object and
  383.      *             is one of the following :
  384.      *             itemListenerK indicating and ItemListener object.
  385.      *
  386.      * @see AWTEventMulticaster.save(ObjectOutputStream, String, EventListener)
  387.      * @see java.awt.Component.itemListenerK
  388.      */
  389.     private void writeObject(java.io.ObjectOutputStream s)
  390.       throws java.lang.ClassNotFoundException,
  391.          java.io.IOException
  392.     {
  393.       s.defaultWriteObject();
  394.     }
  395.  
  396.     /**
  397.      * Read the ObjectInputStream and if it isnt null
  398.      * add a listener to receive item events fired
  399.      * by the MenuBar.
  400.      * Unrecognised keys or values will be Ignored.
  401.      *
  402.      * @see removeActionListener()
  403.      * @see addActionListener()
  404.      */
  405.     private void readObject(java.io.ObjectInputStream s)
  406.       throws java.lang.ClassNotFoundException,
  407.          java.io.IOException
  408.     {
  409.       s.defaultReadObject();
  410.       for (int i = 0; i < menus.size(); i++) {
  411.     Menu m = (Menu)menus.elementAt(i);
  412.     m.parent = this;
  413.       }
  414.     }
  415.  
  416.     /**
  417.      * Initialize JNI field and method IDs
  418.      */
  419.     private static native void initIDs();
  420. }
  421.